<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式与数据劫持</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <!-- <script src="../js/myvue.js"></script> -->
</head>

<body>

    <!-- 
        一、什么是响应式？
            修啊data后，页面自动刷新/改变。这就是响应式
        二、Vue的响应式是如何实现的？
            数据劫持：Vue底层使用了Object.defineProperty，配置了setter方法，当去修改属
            性值时setter方法则被自动调用，setter方法中不仅修改了属性，而且做了其他事情，
            例如：重新渲染也买你。setter方法就像半路劫持一样，所以称为数据劫持。
    -->
    <div id="app">
        <h1>{{msg}}</h1>
        <div>姓名：{{name}}</div>
        <div>年龄：{{age}}岁</div>
        <div>数字：{{a.b.c.e}}</div>
    </div>

    <script>

        const vm = new Vue({
            el: '#app',
            data: {
                msg: '响应式与数据劫持',
                name: 'zhangsan',
                age: 20,
                a: {
                    b: {
                        c: {
                            e: 1
                        }
                    }
                }
            }
        })

        //测试：后期给Vue实例动态的追加一些属性，会添加响应式处理吗？

        //目前来看，通过给vm追加属性的方式，并没有添加响应式处理
        vm.$data.a.address = 'xxx街道xxx号'


        //以下两种方式可以实现响应式处理
        //语法格式：Vue.set(目标对象,属性名，属性值) ；
        Vue.set(vm.$data.a, 'email', '123@123.com')
        //语法格式二：vm.$set(目标对象,属性名，属性值)
        //vm.$data.a因为数据代理，可以省略为vm.a
        vm.$set(vm.a, 'phone', '156****1056')


        //避免在运行时，向Vue实例或其根$data添加相应式
        //不能直接给 vm / vm.$data 追加响应式属性，只能在声明时提前定义好
        Vue.set(vm, 'x', 1) //error
        Vue.set(vm.$data, 'y', '1') //error


    </script>

</body>

</html>